#include <glib-2.0/glib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

#include "nio.h"

int
nio_packet_send(gnutls_session_t session,
				void *data,
				size_t len)
{
	size_t total = 0;
	size_t bytesleft = len;
	size_t n;

	while(total < len) {
    	n = gnutls_record_send(session, data+total, bytesleft);
	    if (n == -1) { break; }
		    total += n;
			    bytesleft -= n;
	}

	len = total;

	return n == -1 ? -1 : 0;
}

int
nio_packet_recv()
{
	return 0;
}

int
nio_send(void *data,
		 size_t size,
		 char flags)
{
	packet_t packet;

	packet.magic = PACKET_MAGIC;
	packet.size = size;
	packet.flags = flags;

	if (nio_packet_send(nio_session, (void *)&packet, sizeof(packet_t)) == -1)
		return -1;

	if (nio_packet_send(nio_session, data, size) == -1)
		return -2;

	return 0;
}

int
nio_recv(void **buffer,
		 char *flags)
{
	packet_t packet;
	int ret;

	ret = gnutls_record_recv(nio_session, &packet, sizeof(packet_t)); 
	if (ret < 1)
		return -1;
	if (packet.magic != PACKET_MAGIC)
		return -2;
	*buffer = g_malloc(packet.size);
	ret = gnutls_record_recv(nio_session, *buffer, packet.size); 
	if (ret < 1)
		return -3;

	return ret;
}

int
nio_init()
{
	/* Need to enable anonymous KX specifically. */
 	const int kx_prio[] = {GNUTLS_KX_ANON_DH, 0};

	gnutls_global_init();
	gnutls_anon_allocate_client_credentials(&nio_cred);
	/* Initialize TLS session 
	 *    */
	gnutls_init(&nio_session, GNUTLS_CLIENT);

    /* Use default priorities */
	gnutls_set_default_priority(nio_session);
	gnutls_kx_set_priority(nio_session, kx_prio);
	/* put the anonymous credentials to the current session */
	gnutls_credentials_set(nio_session, GNUTLS_CRD_ANON, &nio_cred);

	return 0;
}


